Header file output_parameter.hpp

namespace type_safe
{
    template <typename T>
    class output_parameter;
    
    template <typename T>
    output_parameter<T> out(T& obj) noexcept;
    
    template <typename T>
    output_parameter<T> out(deferred_construction<T>& o) noexcept;
}

Class template type_safe::output_parameter

template <typename T>
class output_parameter
{
public:
    using parameter_type = T;
    
    output_parameter(T& obj) noexcept;
    
    output_parameter(const T&) = delete;
    output_parameter(T&&) = delete;
    output_parameter(const T&&) = delete;
    
    output_parameter(deferred_construction<T>& out) noexcept;
    
    output_parameter(const deferred_construction<T>&) = delete;
    output_parameter(deferred_construction<T>&&) = delete;
    output_parameter(const deferred_construction<T>&&) = delete;
    
    output_parameter(output_parameter&& other) noexcept;
    
    ~output_parameter() noexcept = default;
    
    output_parameter& operator=(const output_parameter&) = delete;
    output_parameter& operator=(output_parameter&&) = delete;
    
    template <typename U>
    typename std::enable_if<std::is_constructible<T, decltype(std::forward<U>(u))>::value, parameter_type&>::type operator=(U&& u);
    
    template <typename ... Args>
    T& assign(Args&&... args);
};

A tiny wrapper modelling an output parameter of a function.

An output parameter is a parameter that will be used to transport output of a function to its caller, like a return value does. Usually they are implemented with lvalue references. They have a couple of disadvantages though:

If you use this class as your output parameter type, you do not have these disadvantages. The creation is explicit, you cannot read the value, and it works with ts::deferred_construction.

Notes: While you could use this class in other locations besides parameters, this is not recommended.

Constructor type_safe::output_parameter::output_parameter

output_parameter(T& obj) noexcept;

Effects: Creates it from an lvalue reference. All output will be assigned to the object referred by the reference.

Requires: The referred object must live as long as the function has not returned.

Constructor type_safe::output_parameter::output_parameter

(1)  output_parameter(const T&) = delete;

(2)  output_parameter(T&&) = delete;

(3)  output_parameter(const T&&) = delete;

Constructor type_safe::output_parameter::output_parameter

output_parameter(deferred_construction<T>& out) noexcept;

Effects: Creates it from a ts::deferred_construction object. All output will be assigned or created in the storage of the defer construction object, depending on wheter it is initialized.

Requires: The referred object must live as long as the function has not returned.

Constructor type_safe::output_parameter::output_parameter

(1)  output_parameter(const deferred_construction<T>&) = delete;

(2)  output_parameter(deferred_construction<T>&&) = delete;

(3)  output_parameter(const deferred_construction<T>&&) = delete;

Move constructor type_safe::output_parameter::output_parameter

output_parameter(output_parameter&& other) noexcept;

Effects: Moves an output parameter. This will put other in an invalid state, it must not be used afterwards.

Notes: This constructor is only there because guaranteed copy elision isn't available and otherwise the out() function could not be implemented. It is not intended to use it otherwise.

Assignment operator type_safe::output_parameter::operator=

(1)  output_parameter& operator=(const output_parameter&) = delete;

(2)  output_parameter& operator=(output_parameter&&) = delete;

Assignment operator type_safe::output_parameter::operator=

template <typename U>
typename std::enable_if<std::is_constructible<T, decltype(std::forward<U>(u))>::value, parameter_type&>::type operator=(U&& u);

Effects: Same as assign(std::forward<U>(u)).

Returns: A reference to the value that was assigned, not *this as normal "assignment" operators. \requires value_type must be constructible from U. \synopsis_return parameter_type&


Function template type_safe::out

template <typename T>
output_parameter<T> out(T& obj) noexcept;

Returns: A new ts::output_parameter using the reference obj as output.

Function template type_safe::out

template <typename T>
output_parameter<T> out(deferred_construction<T>& o) noexcept;

Returns: A new ts::output_parameter using the ts::deferred_construction as output.